package com.bestcem.xm.ticket.grpc.client;

import cn.hutool.core.lang.ObjectId;
import cn.hutool.core.util.StrUtil;
import com.bestcem.bp.grpc.v1.base.Page;
import com.bestcem.bp.xm.user.grpc.v1.services.*;
import com.bestcem.xm.common.core.constant.GrpcClientNames;
import com.bestcem.xm.ticket.grpc.client.convert.TicketBaseUserConvert;
import com.bestcem.xm.ticket.grpc.client.dto.user.GroupDTO;
import com.bestcem.xm.ticket.grpc.client.dto.user.GroupNodeDTO;
import com.bestcem.xm.ticket.grpc.client.dto.user.IdMapNodeDTO;
import com.bestcem.xm.ticket.grpc.client.dto.user.UserDTO;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;

import static com.bestcem.bp.grpc.v1.base.Code.ERROR;

/**
 * 工单调用 user 模块相关rpc接口客户端
 *
 * @author XiaoYunSong <ys.xiao@idiaoyan.com>
 * @version v1.0
 * @date 2021/8/30 16:34
 */
@Slf4j
@Service
public class TicketUserGrpcService {

    @GrpcClient(GrpcClientNames.DS_USER)
    private UserServiceGrpc.UserServiceBlockingStub userServiceBlockingStub;

    @GrpcClient(GrpcClientNames.DS_USER)
    private UserGroupServiceGrpc.UserGroupServiceBlockingStub userGroupServiceBlockingStub;

    @GrpcClient(GrpcClientNames.DS_USER)
    private OrgServiceGrpc.OrgServiceBlockingStub orgServiceBlockingStub;

    @GrpcClient(GrpcClientNames.DS_USER)
    private UserRoleServiceGrpc.UserRoleServiceBlockingStub userRoleServiceBlockingStub;

    /**
     * 获取组织的超级管理员id
     *
     * @param orgId
     * @return
     */
    @Nonnull
    public List<String> listAdminIds(String orgId) {
        if (!ObjectId.isValid(orgId)) {
            return new ArrayList<>();
        }
        ListAdminIdsRequest.Builder builder = ListAdminIdsRequest.newBuilder();
        builder.setOrgId(orgId);
        try {
            ListAdminIdsResponse response = userServiceBlockingStub.listAdminIds(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket]: 查询组织超级管理员 USER listAdminUsers {} Error; ErrorMsg: {}", orgId, response);
                return new ArrayList<>();
            }
            return response.getIdsList();
        } catch (Exception e) {
            log.error("[Ticket]: 查询组织超级管理员 USER listAdminUsers {} Error", orgId, e);
            return new ArrayList<>();
        }
    }

    /**
     * 根据user_id 获取 祖先层级 ids
     *
     * @param userId 用户id
     * @return 祖先层级id列表
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/30 16:49
     */
    @Nullable
    public List<String> listAncestorIdsByUserId(String userId) {
        ListAncestorGroupIdsByUidRequest.Builder builder = ListAncestorGroupIdsByUidRequest.newBuilder();
        if (StrUtil.isEmpty(userId)) {
            return Collections.emptyList();
        }
        builder.setUserId(userId);
        try {
            ListAncestorGroupIdsByUidResponse response = userGroupServiceBlockingStub.listAncestorGroupIdsByUid(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER listAncestorIdsByUserId {} Error; ErrorMsg: {}", userId, response);
                return null;
            }
            return response.getIdsList();
        } catch (Exception e) {
            log.error("[Ticket] USER listAncestorIdsByUserId {} Error", userId, e);
            return null;
        }
    }

    /**
     * 根据group_id 获取 祖先层级 ids
     *
     * @param groupId groupId
     * @return 祖先层级id列表
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/30 16:49
     */
    @Nullable
    public List<GroupNodeDTO> listAncestorGroupsByGroupId(String groupId) {
        ListAncestorStoresByIdRequest.Builder builder = ListAncestorStoresByIdRequest.newBuilder();
        builder.setGroupId(groupId);
        try {
            ListAncestorStoresByIdResponse response =
                    userGroupServiceBlockingStub.listAncestorStoresById(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER listAncestorGroupsByGroupId {} Error; ErrorMsg: {}", groupId, response);
                return null;
            }
            return TicketBaseUserConvert.groupBaseToGroupNodeDTOList(response.getStoresList());
        } catch (Exception e) {
            log.error("[Ticket] USER listAncestorGroupsByGroupId {} Error; ErrorMsg: {}", groupId, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 通过 root_group_id 获取该门店层级结构和子门店层级结构
     *
     * @param rootGroupId     root_group_id
     * @param includeInactive 是否包含失效节点
     * @return 层级结构
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/30 17:09
     */
    @Nullable
    public GroupNodeDTO getGroupTreeByRootGroupId(String rootGroupId, boolean includeInactive) {
        GetGroupTreeByGroupIdRequest.Builder builder = GetGroupTreeByGroupIdRequest.newBuilder();
        builder.setGroupId(rootGroupId);
        builder.setIncludeInactive(includeInactive);
        try {
            GetGroupTreeByGroupIdResponse response =
                    userGroupServiceBlockingStub.getGroupTreeByGroupId(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER getGroupTreeByRootGroupId {}-{} Error; ErrorMsg: {}",
                        rootGroupId, includeInactive, response);
                return null;
            }
            return TicketBaseUserConvert.toGroupNodeDTO(response.getTree());
        } catch (Exception e) {
            log.error("[Ticket] USER getGroupTreeByRootGroupId {}-{} Error; ErrorMsg: {}",
                    rootGroupId, includeInactive, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 根据org_id 获取总部层级结构
     *
     * @param orgId 公司id
     * @return 总部层级结构
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/30 17:12
     */
    @Nullable
    public List<GroupDTO> listHeadQuarterGroupsByOrgId(String orgId) {
        ListGroupsByOrgIdOrParentIdRequest.Builder builder = ListGroupsByOrgIdOrParentIdRequest.newBuilder();
        builder.setOrgId(orgId);
        try {
            ListGroupsByOrgIdOrParentIdResponse response =
                    userGroupServiceBlockingStub.listGroupsByOrgIdOrParentId(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER listHeadQuarterGroupsByOrgId {} Error; ErrorMsg: {}", orgId, response);
                return new ArrayList<>();
            }
            return TicketBaseUserConvert.toGroupDTOList(response.getGroupsList());
        } catch (Exception e) {
            log.error("[Ticket] USER listHeadQuarterGroupsByOrgId {} Error; ErrorMsg: {}", orgId, e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    /**
     * 根据 org code 获取 orgId
     *
     * @param code 公司code
     * @return orgId
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/30 17:20
     */
    @Nullable
    public String getOrgIdByCode(String code) {
        GetOrgByIdOrCodeRequest.Builder builder = GetOrgByIdOrCodeRequest.newBuilder();
        builder.setCode(code);
        try {
            GetOrgByIdOrCodeResponse response =
                    orgServiceBlockingStub.getOrgByIdOrCode(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER getOrganizationByCode {} Error; ErrorMsg: {}", code, response);
                return null;
            }
            return Optional.ofNullable(response.getOrg()).map(Organization::getId).orElse(null);
        } catch (Exception e) {
            log.error("[Ticket] USER getOrganizationByCode {} Error", code, e);
            return null;
        }
    }

    /**
     * 根据org_id 获取根层级结构
     *
     * @param orgId 公司id
     * @return 根层级结构
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/30 17:20
     */
    @Nullable
    public GroupDTO getRootGroupByOrgId(String orgId) {
        GetRootGroupRequest.Builder builder = GetRootGroupRequest.newBuilder();
        builder.setOrgId(orgId);
        try {
            GetRootGroupResponse response = userGroupServiceBlockingStub
                    .getRootGroup(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER getRootGroupByOrgId {} Error; ErrorMsg: {}", orgId, response);
                return null;
            }
            return TicketBaseUserConvert.toGroupDTO(response.getGroup());
        } catch (Exception e) {
            log.error("[Ticket] USER getRootGroupByOrgId {} Error", orgId, e);
            return null;
        }
    }

    /**
     * 根据 group_ids, level_id 获取子层级
     *
     * @param groupIds groupId 列表
     * @param levelId  层ID
     * @return 子层级信息
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/30 17:30
     */
    @Nullable
    public List<GroupNodeDTO> listSubGroupsByGroupIdsAndLevelId(List<String> groupIds, String levelId) {
        try {
            if (!ObjectUtils.isEmpty(levelId)) {
                ListSubRelatedGroupsRequest.Builder builder = ListSubRelatedGroupsRequest.newBuilder();
                builder.addAllGroupIds(groupIds);
                builder.setGroupLevelId(levelId);
                ListSubRelatedGroupsResponse response =
                        userGroupServiceBlockingStub.listSubRelatedGroups(builder.build());
                if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                    log.error("[Ticket] USER listSubGroupsByGroupIdsAndLevelId {}-{} Error; ErrorMsg: {}"
                            , groupIds, levelId, response);
                    return null;
                }
                return TicketBaseUserConvert.groupBaseToGroupNodeDTOList(response.getGroupsList());
            } else {
                ListSubGroupsByGroupIdsRequest.Builder builder = ListSubGroupsByGroupIdsRequest.newBuilder();
                builder.addAllGroupIds(groupIds);
                ListSubGroupsByGroupIdsResponse response =
                        userGroupServiceBlockingStub.listSubGroupsByGroupIds(builder.build());
                if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                    log.error("[Ticket] USER listSubGroupsByGroupIdsAndLevelId {}-{} Error; ErrorMsg: {}"
                            , groupIds, levelId, response);
                    return null;
                }
                return TicketBaseUserConvert.groupBaseToGroupNodeDTOList(response.getGroupsList());
            }
        } catch (Exception e) {
            log.error("[Ticket] USER listSubGroupsByGroupIdsAndLevelId {}-{} Error"
                    , groupIds, levelId, e);
            return null;
        }
    }

    /**
     * 根据 role_id 获取用户列表
     *
     * @param roleId 角色id
     * @return 用户列表
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/30 17:35
     */
    @Nullable
    public List<UserDTO> listUsersByRoleId(String roleId) {
        ListUsersByRoleIdRequest.Builder builder = ListUsersByRoleIdRequest.newBuilder();
        if (StrUtil.isNotEmpty(roleId)) {
            builder.setRoleId(roleId);
        }
        try {
            ListUsersByRoleIdResponse response =
                    userServiceBlockingStub.listUsersByRoleId(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER listUsersByRoleId {} Error; ErrorMsg: {}", roleId, response);
                return null;
            }
            return TicketBaseUserConvert.toUserDTOList(response.getUsersList());
        } catch (Exception e) {
            log.error("[Ticket] USER listUsersByRoleId {} Error", roleId, e);
            return null;
        }
    }

    /**
     * 根据 role_id ,group_id,level_id获取用户列表
     *
     * @param roleId 角色id
     * @return 用户列表
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/30 17:35
     */
    @Nullable
    public List<UserDTO> listUsersByRole(String roleId, String groupId, String levelId) {
        ListUsersByRoleIdRequest.Builder builder = ListUsersByRoleIdRequest.newBuilder();
        if (StrUtil.isNotEmpty(roleId)) {
            builder.setRoleId(roleId);
        }
        if (StrUtil.isNotEmpty(groupId)) {
            builder.setGroupId(groupId);
        }
        if (StrUtil.isNotEmpty(levelId)) {
            builder.setLevelId(levelId);
        }
        try {
            ListUsersByRoleIdResponse response =
                    userServiceBlockingStub.listUsersByRoleId(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER listUsersByRoleId {} Error; ErrorMsg: {}", roleId, response);
                return null;
            }
            return TicketBaseUserConvert.toUserDTOList(response.getUsersList());
        } catch (Exception e) {
            log.error("[Ticket] USER listUsersByRoleId {} Error; ErrorMsg: {}"
                    , roleId, e.getMessage(), e);
            return null;
        }
    }

    /**
     * copy_sample 复制旧公司 group_level
     *
     * @param srcId 旧公司ID
     * @param dstId 新公司ID
     * @return id对应关系
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/30 17:39
     */
    @Nullable
    public List<IdMapNodeDTO> getGroupLevelMapBySrcIdAndDstId(String srcId, String dstId) {
        ListSampleGroupLevelIdsRequest.Builder builder = ListSampleGroupLevelIdsRequest.newBuilder();
        builder.setSrcOrgId(srcId);
        builder.setDstOrgId(dstId);
        try {
            ListSampleGroupLevelIdsResponse response =
                    userGroupServiceBlockingStub.listSampleGroupLevelIds(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER getGroupLevelMapBySrcIdAndDstId {}-{} Error; ErrorMsg: {}", srcId, dstId, response);
                return null;
            }
            return TicketBaseUserConvert.toIdMapNodeDTOList(response.getIdRelationsList());
        } catch (Exception e) {
            log.error("[Ticket] USER getGroupLevelMapBySrcIdAndDstId {}-{} Error", srcId, dstId, e);
            return null;
        }
    }

    /**
     * copy_sample 复制旧公司 group
     *
     * @param srcId 旧公司ID
     * @param dstId 新公司ID
     * @return id对应关系
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/30 17:39
     */
    @Nullable
    public List<IdMapNodeDTO> getGroupMapBySrcIdAndDstId(String srcId, String dstId) {
        ListSampleGroupIdsRequest.Builder builder = ListSampleGroupIdsRequest.newBuilder();
        builder.setSrcOrgId(srcId);
        builder.setDstOrgId(dstId);
        try {
            ListSampleGroupIdsResponse response =
                    userGroupServiceBlockingStub.listSampleGroupIds(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER getGroupMapBySrcIdAndDstId {}-{} Error; ErrorMsg: {}", srcId, dstId, response);
                return null;
            }
            return TicketBaseUserConvert.toIdMapNodeDTOList(response.getIdRelationsList());
        } catch (Exception e) {
            log.error("[Ticket] USER getGroupMapBySrcIdAndDstId {}-{} Error", srcId, dstId, e);
            return null;
        }
    }

    /**
     * copy_sample 复制旧公司user
     *
     * @param srcId 旧公司ID
     * @param dstId 新公司ID
     * @return id对应关系
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/30 17:39
     */
    @Nullable
    public List<IdMapNodeDTO> getUserMapBySrcIdAndDstId(String srcId, String dstId) {
        ListUserIdMapsRequest.Builder builder = ListUserIdMapsRequest.newBuilder();
        builder.setSrcOrgId(srcId);
        builder.setDstOrgId(dstId);
        try {
            ListUserIdMapsResponse response =
                    userServiceBlockingStub.listUserIdMaps(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER getUserMapBySrcIdAndDstId {}-{} Error; ErrorMsg: {}", srcId, dstId, response);
                return null;
            }
            return TicketBaseUserConvert.toIdMapNodeDTOList(response.getIdRelationsList());
        } catch (Exception e) {
            log.error("[Ticket] USER getUserMapBySrcIdAndDstId {}-{} Error", srcId, dstId, e);
            return null;
        }
    }

    /**
     * copy_sample 复制旧公司role
     *
     * @param srcId 旧公司ID
     * @param dstId 新公司ID
     * @return id对应关系
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/30 17:39
     */
    @Nullable
    public List<IdMapNodeDTO> getRoleMapBySrcIdAndDstId(String srcId, String dstId) {
        ListSampleRoleIdsRequest.Builder builder = ListSampleRoleIdsRequest.newBuilder();
        builder.setSrcOrgId(srcId);
        builder.setDstOrgId(dstId);
        try {
            ListSampleRoleIdsResponse response =
                    userRoleServiceBlockingStub.listSampleRoleIds(builder.build());
            if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                log.error("[Ticket] USER getRoleMapBySrcIdAndDstId {}-{} Error; ErrorMsg: {}", srcId, dstId, response);
                return null;
            }
            return TicketBaseUserConvert.toIdMapNodeDTOList(response.getIdRelationsList());
        } catch (Exception e) {
            log.error("[Ticket] USER getRoleMapBySrcIdAndDstId {}-{} Error", srcId, dstId, e);
            return null;
        }
    }


    /**
     * 获取用户当前所有直接关联的层级的信息
     *
     * @param userId 用户id
     * @return group info
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/12/31 14:20
     */
    @Nonnull
    public List<GroupDTO> getUserCurrentGroup(String userId) {
        int total, page = 1;
        List<GroupDTO> result = new ArrayList<>();
        if (!ObjectId.isValid(userId)) {
            return result;
        }
        do {
            ListGroupsByUidRequest.Builder builder = ListGroupsByUidRequest.newBuilder();
            Page.Builder pageBuilder = Page.newBuilder();
            pageBuilder.setPage(page);
            pageBuilder.setSize(1000);
            builder.setPage(pageBuilder.buildPartial());
            builder.setUserId(userId);

            try {
                ListGroupsByUidResponse response = userGroupServiceBlockingStub.listGroupsByUid(builder.buildPartial());
                if (Objects.isNull(response) || ERROR.equals(response.getStatus().getCode())) {
                    log.error("[Ticket] USER getUserCurrentGroup {} Error; ErrorMsg: {}", userId, response);
                    return result;
                }
                total = response.getTotal();
                List<GroupDTO> groupDTOS = TicketBaseUserConvert.toGroupDTOList(response.getGroupsList());
                if (CollectionUtils.isEmpty(groupDTOS)) {
                    break;
                }
                result.addAll(groupDTOS);
            } catch (Exception e) {
                log.error("[Ticket] USER getUserCurrentGroup {} Error", userId, e);
                return result;
            }
            page += 1;
        }
        while (result.size() < total);

        return result;
    }


}
